﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using Utilities;

namespace PayexpDAL
{
    public class FilterCriteria
    {
        public FilterCriteria(bool limitTheNumberOfRecords)
        {
            this._limitTheNumberOfRecords = limitTheNumberOfRecords;
        }

        public bool ReconciliationMode
        {
            get;
            set;
        }
        
        public bool OnlyReconciledRecords
        {
            get;
            set;
        }

        public bool OnlyUnreconciledRecords
        {
            get;
            set;
        }

        public bool OnlyIncomeRecords
        {
            get;
            set;
        }

        public bool OnlyExpenseRecords
        {
            get;
            set;
        }

        public bool RunningBalanceComputed
        {
            get;
            set;
        }
        
        private bool _limitTheNumberOfRecords;

        public bool LimitTheNumberOfRecords
        {
            get { return _limitTheNumberOfRecords; }
        }

        private DateTime? _dateFrom;

        public DateTime? DateFrom
        {
            get { return _dateFrom; }
            set { _dateFrom = value; }
        }

        private DateTime? _dateTo;

        public DateTime? DateTo
        {
            get { return _dateTo; }
            set { _dateTo = value; }
        }

        private decimal? _amountFrom;

        public decimal? AmountFrom
        {
            get { return _amountFrom; }
            set { _amountFrom = value; }
        }

        private decimal? _amountTo;

        public decimal? AmountTo
        {
            get { return _amountTo; }
            set { _amountTo = value; }
        }

        private int? _chequeNumberFrom;

        public int? ChequeNumberFrom
        {
            get { return _chequeNumberFrom; }
            set { _chequeNumberFrom = value; }
        }

        private int? _chequeNumberTo;

        public int? ChequeNumberTo
        {
            get { return _chequeNumberTo; }
            set { _chequeNumberTo = value; }
        }

        private int? _voucherReceiptFrom;

        public int? VoucherReceiptFrom
        {
            get { return _voucherReceiptFrom; }
            set { _voucherReceiptFrom = value; }
        }

        private int? _voucherReceiptTo;

        public int? VoucherReceiptTo
        {
            get { return _voucherReceiptTo; }
            set { _voucherReceiptTo = value; }
        }

        public bool? IsVoucherSelected
        {
            get;
            set;
        }

        public bool? IncludeDeletedTransactions
        {
            get;
            set;
        }

        private int? _firstHeadDetailsId;

        public int? FirstHeadDetailsId
        {
            get { return _firstHeadDetailsId; }
            set { _firstHeadDetailsId = value; }
        }

        public List<TransactionType> FirstHeadDetailsHierarchy { get; set; }

        private int? _secondHeadDetailsId;

        public int? SecondHeadDetailsId
        {
            get { return _secondHeadDetailsId; }
            set { _secondHeadDetailsId = value; }
        }

        public List<TransactionType> SecondHeadDetailsHierarchy { get; set; }

        private int? _thirdHeadDetailsId;

        public int? ThirdHeadDetailsId
        {
            get { return _thirdHeadDetailsId; }
            set { _thirdHeadDetailsId = value; }
        }

        public List<TransactionType> ThirdHeadDetailsHierarchy { get; set; }

        private string _narration;

        public string Narration
        {
            get { return _narration; }
            set { _narration = value; }
        }

        private bool _transactionDateSelected = true;

        public bool TransactionDateSelected
        {
            get { return _transactionDateSelected; }
            set { _transactionDateSelected = value; }
        }

        private List<BankAccount> _bankAccountsList = new List<BankAccount>();

        public List<BankAccount> BankAccountsList
        {
            get { return _bankAccountsList; }
        }
        
        public List<int> BankAccountsIdList
        {
            get 
            {
                if (this._bankAccountsList.Count > 0)
                {
                    return this._bankAccountsList.Select(t => t.Id).ToList();
                }
                else
                {
                    return new List<int>();
                }
            }
        }

        private List<StaticList> _transactionModeList = new List<StaticList>();

        public List<StaticList> TransactionModeList
        {
            get { return _transactionModeList; }
            set { _transactionModeList = value; }
        }

        public List<string> TransactionModeStringList
        {
            get
            {
                if (this._transactionModeList.Count > 0)
                {
                    return this._transactionModeList.Select(t => t.ListItemCode).ToList();
                }
                else
                {
                    return new List<string>();
                }
            }
        }

        private List<ExpenseApprover> _expenseApproverList = new List<ExpenseApprover>();

        public List<ExpenseApprover> ExpenseApproverList
        {
            get { return _expenseApproverList; }
        }

        public List<string> ExpenseApproverIdSquareBracketedList
        {
            get 
            {
                if (this._expenseApproverList.Count > 0)
                {
                    return this._expenseApproverList.Select(t => "[" + t.Id.ToString() + "]").ToList();
                }
                else
                {
                    return new List<string>();
                }
            }
        }
        
        private int? _pageNumber = 0;

        public int? PageNumber
        {
            get { return _pageNumber; }
            set { _pageNumber = value; }
        }

        private int? _numberOfRecords = 30; // default

        public int? NumberOfRecords
        {
            get { return _numberOfRecords; }
            set { _numberOfRecords = value; }
        }

        public string FiltersUsedAsText
        {
            get
            {
                List<string> temp = new List<string>();
                List<string> headDetailsText = new List<string>();
                if (this._dateFrom.HasValue)
                {
                    if (this.TransactionDateSelected)
                    {
                        temp.Add(string.Format("Transaction date from '{0}' To '{1}'",
                                this._dateFrom.Value.Get_DD_MONTH_YY_DateString(),
                                this._dateTo.Value.Get_DD_MONTH_YY_DateString()));
                    }
                    else
                    {
                        temp.Add(string.Format("Bank date from '{0}' To '{1}'",
                                this._dateFrom.Value.Get_DD_MONTH_YY_DateString(),
                                this._dateTo.Value.Get_DD_MONTH_YY_DateString()));
                    }
                }

                if (this._amountFrom.HasValue)
                {
                    
                    temp.Add(string.Format("Amount from 'INR {0}' to 'INR {1}'",
                            this._amountFrom.Value,
                            this._amountTo.Value));
                }

                if (this._chequeNumberFrom.HasValue)
                {

                    temp.Add(string.Format("Cheque number from '{0}' To '{1}'",
                            this._chequeNumberFrom.Value,
                            this._chequeNumberTo.Value));
                }

                if (!string.IsNullOrEmpty(this._narration))
                {
                    temp.Add(string.Format("Narration contains the word(s) '{0}'", this._narration));
                }

                if (this._firstHeadDetailsId.HasValue && this.FirstHeadDetailsHierarchy != null && this.FirstHeadDetailsHierarchy.Count > 0)
                {

                    string headText = "'" + string.Join("-->", this.FirstHeadDetailsHierarchy.Select(t => t.Name).ToArray()) + "'"; 
                    headDetailsText.Add(headText);
                }

                if (this._secondHeadDetailsId.HasValue && this.SecondHeadDetailsHierarchy != null && this.SecondHeadDetailsHierarchy.Count > 0)
                {

                    string headText = "'" + string.Join("-->", this.SecondHeadDetailsHierarchy.Select(t => t.Name).ToArray()) + "'";
                    headDetailsText.Add(headText);
                }

                if (this._thirdHeadDetailsId.HasValue && this.ThirdHeadDetailsHierarchy != null && this.ThirdHeadDetailsHierarchy.Count > 0)
                {

                    string headText = "'" + string.Join("-->", this.ThirdHeadDetailsHierarchy.Select(t => t.Name).ToArray()) + "'";
                    headDetailsText.Add(headText);
                }

                if(headDetailsText.Count > 0)
                {
                    string headFilterText = string.Join(" Or ", headDetailsText.ToArray());
                    headFilterText = "Head details under '" + headFilterText + "'";
                    temp.Add(headFilterText);
                }

                if (this.TransactionModeList.Count > 0)
                {
                    string transactionModeText = string.Join(" Or ", this.TransactionModeList.Select(t => t.ListItemValue).ToArray());
                    transactionModeText = "Transaction mode is '" + transactionModeText + "'";
                    temp.Add(transactionModeText);
                }

                if (this.ExpenseApproverList.Count > 0)
                {
                    string expenseApproverText = string.Join(" Or ", this.ExpenseApproverList.Select(t => t.DisplayName).ToArray());
                    expenseApproverText = "Expense approver is '" + expenseApproverText + "'";
                    temp.Add(expenseApproverText);
                }

                if (this.BankAccountsList.Count > 0)
                {
                    string bankNameText = string.Join(" Or ", this.BankAccountsList.Select(t => t.BankDisplayName).ToArray());
                    bankNameText = "Transaction bank is '" + bankNameText + "'";
                    temp.Add(bankNameText);
                }

                if (this.IsVoucherSelected.HasValue)
                {
                    if (this.IsVoucherSelected.Value)
                    {
                        temp.Add(string.Format("Voucher number from '{0}' to '{1}'",
                               this._voucherReceiptFrom.Value,
                               this._voucherReceiptTo.Value));
                    }
                    else
                    {
                        temp.Add(string.Format("Receipt number from '{0}' to '{1}'",
                               this._voucherReceiptFrom.Value,
                               this._voucherReceiptTo.Value));
                    }
                    
                }

                if (this.TransactionMasterIdList.Count > 0)
                {
                    temp.Add(string.Format("Transaction Master Id is '{0}'",
                                            string.Join(" Or ",this.TransactionMasterIdList)));
                }

                if (this.IncludeDeletedTransactions.HasValue)
                {
                    if (this.IncludeDeletedTransactions.Value)
                    {
                        temp.Add("Include deleted transactions as well");
                    }
                    else
                    {
                        temp.Add("Fetch only deleted transactions");
                    }
                }

                return string.Format("This report contains transactions which match the criteria: {0}",
                                              string.Join(" And ", temp.ToArray()));
            }
        }

        public bool HasError
        {
            get;
            set;
        }

        public List<string> ValidationErrorList
        {
            get;
            set;
        }

        private List<int> _transactionMasterIdList = new List<int>();

        public List<int> TransactionMasterIdList
        {
            get { return _transactionMasterIdList; }
            set { _transactionMasterIdList = value; }
        }
    }
}
